package com.rpc.center.register.client.netty;

import com.rpc.center.register.client.RPCRegisterService;
import com.rpc.common.entity.HostInfoPair;
import com.rpc.common.entity.request.DiscoverDTO;
import com.rpc.common.entity.request.PublishDTO;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.Setter;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

public class NettyRegisterServiceImpl implements RPCRegisterService {
    private AtomicBoolean isStart=new AtomicBoolean(false);
    private AtomicBoolean isStartSuccess=new AtomicBoolean(false);
    private String serverAddress;
    private int serverPort;
    @Setter
    private Channel channel;
    private NettyRegistServiceHandler handler;
    private PipleLineInitializer pipleLine;
    public NettyRegisterServiceImpl(String serverAddress, int servePort) {
        this.serverAddress = serverAddress;
        this.serverPort = servePort;
    }

    private void startClient(){
        if(isStart.compareAndSet(false,true)){
            pipleLine=new PipleLineInitializer(this);
            handler=pipleLine.getHandler();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Bootstrap bootstrap=new Bootstrap();
                    EventLoopGroup eventLoopGroup=new NioEventLoopGroup();
                    try{
                        bootstrap.group(eventLoopGroup)
                                .channel(NioSocketChannel.class)
                                .option(ChannelOption.TCP_NODELAY,true)
                                .remoteAddress(new InetSocketAddress(serverAddress, serverPort))
                                .handler(pipleLine);
                        ChannelFuture f = bootstrap.connect().sync();
                        //添加关闭钩子。优雅下线
//                Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
//                    @Override
//                    public void run() {
//                        if(f.isSuccess()){
//                            OffLinePacket offLinePacket=new OffLinePacket();
//                            PropertiesUtil readUtil=PropertiesUtil.getPropertiesUtil();
//                            offLinePacket.setAddress(readUtil.getHostAddress());
//                            offLinePacket.setPort(readUtil.getPort());
//                            nettyHarmonyService.offline(offLinePacket);
//                        }
//                    }
//                }));
                        f.addListener(future -> {
                            if(future.isSuccess()){
                                isStartSuccess.compareAndSet(false,true);
                                channel=f.channel();
                            }
                        });
                        f.channel().closeFuture().sync();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            eventLoopGroup.shutdownGracefully().sync();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }


    @Override
    public boolean publish(PublishDTO publishDTO) {
        startClient();
        if(channel==null){
            while (!isStartSuccess.get()){
                //自旋等待
            }
        }
        channel.writeAndFlush(publishDTO);
        CountDownLatch latch=new CountDownLatch(1);
        //handler.setLatch(latch);

//        future.addListener(future1 -> {
//            if(future1.isSuccess()){
//                System.out.println("发送成功");
//            }else{
//                System.out.println("发送失败");
//            }
//        });
//        try {
//            latch.await(1,TimeUnit.SECONDS);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//            return false;
//        }
        return handler.isPublishSuccess();
    }
}
